<template>
  <bodyBg />
  <topBg />
  <div class="bodyDiv" @dragover.prevent @drop="onDrop">
    <!-- 添加画布设计区域 -->
    <div class="canvas">
      <div
        v-for="(item, index) in canvasItems"
        :key="item.id"
        class="dragDiv cloned"
        :style="[
          'left:' + item.x + 'px;top:' + item.y + 'px;',
          '' + item.containerStyle + '',
        ]"
        draggable="true"
        @dragstart="onCanvasDragStart(index, $event)"
        @contextmenu.prevent="showContextMenu($event, index)"
      >
        <component
          :is="item.bgPath"
          :styleObj="{
            width: 'calc(100% - 25px)',
            height: getDynamicHeight(item.containerStyle),
          }"
        />
        <div :style="'' + item.chartStyle + ''">
          <component :is="item.path" />
        </div>
        <div
          v-if="activeMenuIndex === index"
          class="context-menu"
          :style="{ left: menuPosition.x + 'px', top: menuPosition.y + 'px' }"
        >
          <button @click="deleteItem(index)">删除</button>
          <!-- <button @click="openSettings(index)">设置</button> -->
        </div>
      </div>
    </div>

    <div class="openDiv" @click="openComp">
      <el-button type="warning" >
        组件管理
      </el-button>
    </div>
    <div class="rightDiv" v-if="isVisable">
      <div class="topDiv">
        <div>
          <el-icon><Notification /></el-icon>
          组件管理控制面板
        </div>
        <div style="display: flex">
          <el-button type="danger" size="mini" @click="savePoint"
            >保存设置</el-button
          >
          <el-button type="danger" size="mini" @click="closeWin"
            >关闭</el-button
          >
        </div>
      </div>
      <div class="checkChartsDiv">
        <div v-for="(item, index) in mainComponents" :key="index">
          <!-- itemDivInner-->
          <div
            draggable="true"
            @dragstart="onDragStart(index, $event)"
            @dragend="onDragEnd"
            :style="[
              'width:300px;height:320px;position:relative;overflow:hidden;',
              isDragging == index ? 'opacity:0.1' : 'opacity:1',
            ]"
          >
            <div class="chartStyle">
              <div :style="item.chartStyle2">
                <component :is="item.comp" />
              </div>
            </div>
            <div class="chartBgStyle">
              <component
                :is="item.componentBg"
                :styleObj="{ width: 'calc(100% - 25px)', height: '260px' }"
              />
            </div>
          </div>
        </div>
      </div>
      <div class="TitleDiv" style="margin-top: 20px">
        <el-pagination
          v-model:current-page="params.pageNum"
          v-model:page-size="params.pageSize"
          :page-sizes="[4, 10, 100, 200]"
          :small="small"
          :disabled="disabled"
          :background="background"
          layout="total, prev, pager, next, jumper"
          :total="params.total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
      <div class="categroyDiv">
        <div class="categroyItem categroyItemSelected">案例1</div>
        <div class="categroyItem">案例2</div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import topBg from "./visualization/bodyBg/topBg.vue";
import bodyBg from "./visualization/bodyBg/bgDiv.vue";
import { ref, onMounted } from "vue";
import Http from "../api/http";
import { Notification } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";

function createComponentMap(components) {
  let newList = components.map((comp) => ({
    index: comp.zj.index,
    name: comp.zj.name,
    componentBg: () => import(/* @vite-ignore */ comp.zj.bgPath),
    component: () => import(/* @vite-ignore */ comp.zj.path),
    containerStyle: comp.zj.containerStyle,
    chartStyle: comp.zj.chartStyle,
    position: comp.zj.position,
  }));
  // console.log("newListaaaaaaaa", newList);

  return newList;
}

const canvasItems = ref<any[]>([]);
const isDragging = ref<number | null>(null);
const onDragStart = (index: number, e: DragEvent) => {
  isDragging.value = index;
  e.dataTransfer?.setData(
    "text/plain",
    JSON.stringify({
      type: "new",
      index,
    })
  );
};

const onDragEnd = () => {
  isDragging.value = null;
};

const aa = (bb: any) => {
  return import(/* @vite-ignore */ bb);
};
const onDrop = async (e: DragEvent) => {
  e.preventDefault();
  const data = e.dataTransfer?.getData("text/plain");
  if (!data) return;

  const { type, index } = JSON.parse(data);

  console.log("data", data);
  if (type == "new") {
    console.log("mainComponents", mainComponents);
    let aaFun = await aa(mainComponents.value[index].path);
    let bbFun = await aa(mainComponents.value[index].bgPath);

    const newItem = {
      id: Date.now(),
      x: e.clientX - 100,
      y: e.clientY - 100,
      name: mainComponents.value[index].name,
      pathVal: mainComponents.value[index].path,
      bgPathVal: mainComponents.value[index].bgPath,
      bgPath: bbFun.default,
      path: aaFun.default,
      chartStyle: mainComponents.value[index].chartStyle,
      containerStyle: mainComponents.value[index].containerStyle,
      remart: mainComponents.value[index].remart,
      category: mainComponents.value[index].category,
      chartStyle2: mainComponents.value[index].chartStyle2,
      controlId: mainComponents.value[index].controlId,
    };
    canvasItems.value.push(newItem);
  } else if (type === "move") {
    const itemIndex = parseInt(index);
    console.log("canvasItems.value[itemIndex]", canvasItems.value[itemIndex]);
    canvasItems.value[itemIndex].x = e.clientX - 100;
    canvasItems.value[itemIndex].y = e.clientY - 100;
    // alert(e.clientX + "-" + e.clientY);
  }
};

const onCanvasDragStart = (index: number, e: DragEvent) => {
  e.dataTransfer?.setData(
    "text/plain",
    JSON.stringify({
      type: "move",
      index,
    })
  );
};



const activeMenuIndex = ref<number | null>(null);
const menuPosition = ref({ x: 0, y: 0 });

const showContextMenu = (e: MouseEvent, index: number) => {
  menuPosition.value = { x: e.clientX, y: e.clientY };
  activeMenuIndex.value = index;
};

const deleteItem = (index: number) => {
  canvasItems.value.splice(index, 1);
  activeMenuIndex.value = null;
};

const openSettings = (index: number) => {
  const itemId = canvasItems.value[index].id;
  alert(`当前元素ID: ${itemId}`);
  activeMenuIndex.value = null;
};

// 点击其他地方关闭菜单
document.addEventListener("click", () => {
  activeMenuIndex.value = null;
});

// 添加组件到左侧区域
async function addComponent(comp: any) {
  console.log("componentName", comp);
  const item = await loadComponent(comp);
  if (item) {
    mainComponents.value.push(item);
  }
}

async function loadComponent(component) {
  try {
    if (component) {
      const item = await component.component();
      const itemBg = await component.componentBg();
      const containerStyle = component.containerStyle;
      const chartStyle = component.chartStyle;
      const chartStyle2 = component.chartStyle2;
      const position = component.position;
      const bgPath = component.bgPath;
      const path = component.path;
      const name = component.name;
      const bgPathVal = component.bgPathVal;
      const pathVal = component.pathVal;
      const remart = component.remart;
      const category = component.category;
      const controlId = component.controlId;
      return {
        comp: item.default,
        componentBg: itemBg.default,
        containerStyle,
        chartStyle,
        chartStyle2,
        position,
        bgPath,
        path,
        name,
        bgPathVal,
        pathVal,
        remart,
        category,
        controlId,
      };
    }
    throw new Error(`Component ${component} not found`);
  } catch (error) {
    console.error(`加载组件 ${component} 失败:`, error);
    return null;
  }
}

const mainComponents = ref<any[]>([]);
let params = ref({ pageNum: 1, pageSize: 4, total: 0 });

const small = ref(false);
const background = ref(false);
const disabled = ref(false);

const handleSizeChange = (val: number) => {
  params.value.pageSize = val;
  loadData();
  //console.log(`${val} items per page`);
};
const handleCurrentChange = (val: number) => {
  //console.log(`current page: ${val}`);
  params.value.pageNum = val;
  loadData();
};

const loadData = () => {
  mainComponents.value.splice(0);
  Http.get("/largeScreen/echartsStore/list", {
    pageNum: params.value.pageNum,
    pageSize: params.value.pageSize,
  }).then(async (res) => {
    console.log("res", res);
    let objs = res.rows;
    params.value.total = res.total;
    let arr = [];
    for (var i = 0; i < objs.length; i++) {
      let comp = objs[i];
      let row = {
        storeIndex: comp.storeIndex,
        name: comp.name,
        componentBg: () => import(/* @vite-ignore */ comp.bgPath),
        component: () => import(/* @vite-ignore */ comp.path),
        bgPath: comp.bgPath,
        path: comp.path,
        bgPathVal: comp.bgPath,
        pathVal: comp.path,
        containerStyle: comp.containerStyle,
        chartStyle: comp.chartStyle,
        chartStyle2: comp.chartStyle2,
        remart: comp.remart,
        category: comp.category,
        controlId: comp.id,
      };
      arr.push(row);
    }

    // 使用for...of循环按顺序等待每个组件加载
    for (const component of arr) {
      await addComponent(component);
    }
  });
};

const canvasLoadItems = ref<any[]>([]);
onMounted(() => {
  loadData();
  //========================//
  Http.get("/largeScreen/checked/listAll").then(async (res) => {
    if (res.code === 200) {
      let data = res.data;
      for (let i = 0; i < data.length; i++) {
        let aaFun = await aa(data[i].path);
        let bbFun = await aa(data[i].bgPath);
        const newItem = {
          id: Date.now(),
          x: data[i].xPoint,
          y: data[i].yPoint,
          name: data[i].name,
          pathVal: data[i].path,
          bgPathVal: data[i].bgPath,
          bgPath: bbFun.default,
          path: aaFun.default,
          chartStyle: data[i].chartStyle,
          containerStyle: data[i].containerStyle,
          remart: data[i].remart,
          category: data[i].category,
          chartStyle2: data[i].chartStyle2,
          controlId: data[i].controlId,
        };
        canvasItems.value.push(newItem);
      }
    }
  });
});

let isVisable = ref(false);
const closeWin = () => {
  isVisable.value = false;
};

const getDynamicHeight = (str) => {
  const heightMatch = str.match(/height:([^;]+)/);
  let heightVal: String | null = null;
  if (heightMatch[1]) {
    const heightNumber = heightMatch[1].match(/\d+/)[0]; // 结果为 "300" (字符串)
    // 如果需要数字类型可以转换
    const heightNum = Number(heightNumber);
    heightVal = heightNum - 25 + "px";
  }

  return heightMatch ? heightVal : "260px";
};

//保存控件坐标位置
const savePoint = () => {
  console.log("canvasItems", canvasItems.value);
  let subObjs: any[] = [];
  canvasItems.value.forEach((item, index) => {
    let obj = {
      id: null,
      xPoint: item.x,
      yPoint: item.y,
      storeIndex: item.storeIndex,
      name: item.name,
      bgPath: item.bgPathVal,
      path: item.pathVal,
      containerStyle: item.containerStyle,
      chartStyle: item.chartStyle,
      chartStyle2: item.chartStyle2,
      remart: item.remart,
      category: item.category,
      controlId: item.controlId,
    };
    subObjs.push(obj);
  });
  console.log("subObjs", subObjs);
  Http.post("/largeScreen/checked/saveControls", {
    dataStr: JSON.stringify(subObjs),
  }).then((res) => {
    console.log("res", res);
    if (res.code == 200) {
      ElMessage({ message: "保存成功！", type: "success" });
    }
  });
};

//打开组件管理
const openComp = () => {
  isVisable.value = true;
};
</script>

<style scoped>
.openDiv{
  position: absolute;
  top: 10px;
  right: 20px;
  z-index: 10;
}
.categroyDiv {
  display: flex;
  justify-content: space-between;
  padding: 20px;
}
.categroyItem {
  background-color: #072953;
  width: calc(50% - 20px);
  height: 80px;
  cursor: pointer;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 24px;
}
.categroyItemSelected {
  background-color: #eaa300;
}
.TitleDiv {
  background-color: #f5f5f5;
  border-bottom: 1px solid #ccc;
  padding: 10px;
  margin: 5px;
}
.topDiv {
  background-color: #f5f5f5;
  border-bottom: 1px solid #ccc;
  padding: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 5px;
}
.checkChartsDiv {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  row-gap: 10px;
  align-content: flex-start;
}
.rightDiv {
  position: fixed;
  top: 0;
  right: 0;
  width: 630px;
  height: 100vh;
  background-color: #1f1f1f;
  z-index: 999;
}
.dragDiv {
  min-width: 350px;
  min-height: 300px;
}
.bodyDiv {
  width: 100%;
  height: 100vh;
}
.canvas {
  position: relative;
  width: 100%;
  height: 100%;
}
.cloned {
  position: absolute;
  cursor: move;
}

.context-menu {
  position: fixed;
  background: white;
  border: 1px solid #ccc;
  padding: 5px;
  z-index: 1000;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}

.context-menu button {
  display: block;
  width: 100%;
  padding: 5px 10px;
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
  border-bottom: 1px solid #eee;
}

.context-menu button:last-child {
  border-bottom: none;
}

.context-menu button:hover {
  background-color: #f0f0f0;
}

.itemDivInner {
  width: 100%;
  height: 35vh;
  overflow: hidden;
  position: relative;
}
.chartStyle {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 2;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.chartBgStyle {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 1;
  width: 100%;
  height: 300px;
  overflow: hidden;
}
</style>
<style></style>
